using System.Collections.Generic;
using Microsoft.Xna.Framework;
using ProtectThePie;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input.Touch;
using Microsoft.Xna.Framework.Audio;
using ThreeThingGame;

namespace ProtectThePieWP7.AdditionalClasses
{
    public enum MenuEntryType
    {
        link,
        lever
    }

    public class MenuEntry
    {
        public bool Enabled;
        public MenuEntryType type;
        private Rectangle rectangle;
        public Vector2 position;
        public Vector2 transPosition;
        public Vector2 transAim;
        private Texture2D texture;
        private bool pressed;
        public string text;
        private SoundEffect clickSound;

        public MenuEntry(Vector2 position, string text, MenuEntryType type, SoundEffect clickSound, Texture2D texture)
        {
            Enabled = true;
            rectangle = new Rectangle((int)position.X - 150, (int)position.Y - 30, 300, 60);
            this.type = type;
            //texture = Game1.menuTexture;
            pressed = false;
            this.text = text;
            this.position = position;
            this.clickSound = clickSound;
            this.texture = texture;
        }

        /// <summary>
        /// Update method for menu entry (button)
        /// </summary>
        /// <param name="touches">Touch Collection of the touchscreen</param>
        /// <returns>returns true if menu entry is triggered</returns>
        public bool Update(TouchCollection touches)
        {
            if (Enabled)
            {
                foreach (TouchLocation tl in touches)
                {
                    if (rectangle.Contains(Vector2Add.Vector2ToPoint(tl.Position)))
                    {
                        switch (tl.State)
                        {
                            case TouchLocationState.Pressed:
                                pressed = true;
                                Game1.soundEngine.PlaySoundEffect(clickSound);
                                return false;
                            case TouchLocationState.Moved:
                                if (!pressed) Game1.soundEngine.PlaySoundEffect(clickSound);
                                pressed = true;
                                return false;
                            case TouchLocationState.Released:
                                pressed = false;
                                return true;
                        }
                    }
                }
            }
            pressed = false;
            return false;
        }

        public void Draw(SpriteBatch spriteBatch, MenuSystemState state)
        {
            if (Enabled)
            switch (state)
            {
                case MenuSystemState.idle:
                    rectangle.X = (int)position.X - rectangle.Width / 2;
                    rectangle.Y = (int)position.Y - rectangle.Height / 2;
                    if (pressed)
                    {
                        spriteBatch.Draw(texture, new Rectangle(rectangle.X + 5, rectangle.Y + 5, rectangle.Width, rectangle.Height), new Color(0.5f, 0.5f, 0, 1));
                        spriteBatch.DrawString(Game1.mainFont, text, new Vector2(rectangle.X + 13, rectangle.Y + 10), Color.DarkRed);
                    }
                    else
                    {
                        spriteBatch.Draw(texture, rectangle, Color.White);
                        spriteBatch.DrawString(Game1.mainFont, text, new Vector2(rectangle.X + 8, rectangle.Y + 5), Color.DarkRed);
                    }
                    break;
                case MenuSystemState.fadeIn:
                    rectangle.X = (int)transPosition.X - rectangle.Width / 2;
                    rectangle.Y = (int)transPosition.Y - rectangle.Height / 2;
                    spriteBatch.Draw(texture, rectangle, Color.White);
                    spriteBatch.DrawString(Game1.mainFont, text, new Vector2(rectangle.X + 8, rectangle.Y + 5), Color.DarkRed);
                    break;
                case MenuSystemState.fadeOut:
                    rectangle.X = (int)transPosition.X - rectangle.Width / 2;
                    rectangle.Y = (int)transPosition.Y - rectangle.Height / 2;
                    spriteBatch.Draw(texture, rectangle, Color.White);
                    spriteBatch.DrawString(Game1.mainFont, text, new Vector2(rectangle.X + 8, rectangle.Y + 5), Color.DarkRed);
                    break;
            }
        }
    }

    public enum MenuSystemState
    {
        fadeIn,
        idle,
        fadeOut,
        finish
    }

    public class MenuSystem
    {
        private MenuSystemState state;
        private List<MenuEntry> menuEntry;
        private SoundEffect menuClickSound;
        private string result;
        private Texture2D menuEntryTexture;

        #region Constructor

        public MenuSystem(SoundEffect menuClickSound, Texture2D menuEntryTexture)
        {
            menuEntry = new List<MenuEntry>();
            state = MenuSystemState.finish;
            this.menuClickSound = menuClickSound;
            this.menuEntryTexture = menuEntryTexture;
        }

        #endregion
        #region Public methods

        public string Update(TouchCollection touches)
        {
            switch (state)
            {
                case MenuSystemState.idle:
                    for (int i = 0; i < menuEntry.Count; i++)
                    {
                        if (menuEntry[i].Update(touches))
                        {
                            if (menuEntry[i].type != MenuEntryType.lever)
                            {
                                FadeOut();
                                result = menuEntry[i].text;
                            }
                            else return menuEntry[i].text;
                        }
                    }                 
                    return "";
                case MenuSystemState.fadeIn:
                    TransitionUpdate();
                    return "";
                case MenuSystemState.fadeOut:
                    if (TransitionUpdate())
                    {
                        state = MenuSystemState.finish;
                        return result;
                    }
                    return "";
                case MenuSystemState.finish:
                    FadeIn();
                    return "";
                default: 
                    return "";
            }
        }

        public void Draw(SpriteBatch spriteBatch)
        {
            for (int i = 0; i < menuEntry.Count; i++)
            {
                menuEntry[i].Draw(spriteBatch, state);
            }
        }

        public void AddMenuEntry(string text, MenuEntryType type)
        {
            if (menuEntry.Count > 0)
            {
                Vector2 position = Vector2.Add(menuEntry[menuEntry.Count - 1].position, new Vector2(0, 80));
                menuEntry.Add(new MenuEntry(position, text, type, menuClickSound, menuEntryTexture));
            }
            else
            {
                menuEntry.Add(new MenuEntry(new Vector2(400, 100), text, type, menuClickSound, menuEntryTexture));
            }
        }

        public void SetEnabledMenuEntry(string name, bool enabled)
        {
            for (int i = 0; i < menuEntry.Count; i++)
            {
                if (menuEntry[i].text == name) menuEntry[i].Enabled = enabled;
            }
        }

        public void ChangeMenyEntryText(string oldText, string newText)
        {
            for (int i = 0; i < menuEntry.Count; i++)
            {
                if (menuEntry[i].text == oldText)
                {
                    menuEntry[i].text = newText;
                    return;
                }
            }
        }

        public void PressButton(string buttonName)
        {
            for (int i = 0; i < menuEntry.Count; i++)
            {
                if (menuEntry[i].text == buttonName)
                {
                    result = buttonName;
                    FadeOut();
                    return;
                }
            }            
        }

        public void FadeOut(string result)
        {
            this.result = result;
            FadeOut();
        }

        #endregion
        #region Private methods

        private bool TransitionUpdate()
        {
            for (int i = 0; i < menuEntry.Count; i++)
            {
                float sub = menuEntry[i].transAim.Y - menuEntry[i].transPosition.Y;

                if (sub < 3)
                {
                    state = MenuSystemState.idle;
                    return true;
                }
                else
                {
                    menuEntry[i].transPosition.Y += sub / 3;
                }
            }
            return false;
        }

        private void FadeIn()
        {
            state = MenuSystemState.fadeIn;

            for (int i = 0; i < menuEntry.Count; i++)
            {
                menuEntry[i].transPosition = new Vector2(400, -30);
                menuEntry[i].transAim = menuEntry[i].position;
            }
        }

        private void FadeOut()
        {
            state = MenuSystemState.fadeOut;

            for (int i = 0; i < menuEntry.Count; i++)
            {
                menuEntry[i].transPosition = menuEntry[i].position;
                menuEntry[i].transAim = new Vector2(400, 540);
            }
        }

        #endregion
    }
}
